#ifndef _EKU_RAMFS_H_
#define _EKU_RAMFS_H_

#ifndef RAMFS_TOOLS
#include <user/ulib.h>
#include <user/file_server.h>

#include <inc/ips.h>
#endif

// file system interface definition
// see file_server.h
int ramfs_read(struct fs_node_t *f, char *buf, int n);
int ramfs_write(struct fs_node_t *f, char *buf, int n);
int ramfs_seek(struct fs_node_t *f, int dir, int n);

int ramfs_open(struct fs_node_t *d, struct fs_node_t *f);
int ramfs_close(struct fs_node_t *f);

int ramfs_stat(struct fs_node_t *d, struct fs_stat_t *attr);
int ramfs_roll(struct fs_node_t *d);

int ramfs_create(struct fs_stat_t *attr, char *filename, int n, struct fs_node_t *d);
int ramfs_remove(struct fs_node_t *d);
int ramfs_move(struct fs_node_t *s, struct fs_node_t *d);
int ramfs_copynode(struct fs_node_t *s, struct fs_node_t *d);

#define RAMFS_NAME_LENGTH 15
#define RAMFS_NODE_COUNT  8192

struct ramfs_data_t;

struct ramfs_node_t
{
	 struct mutex_t lock;
	 
	 /* 文件名 */
	 char name[RAMFS_NAME_LENGTH + 1];
	 /* 类型 */
	 uint8_t type;
	 /* 兄弟节点 */
	 struct ramfs_node_t *next;
	 struct ramfs_node_t *prev;
	 
	 /* 如果是文件夹 则有儿子节点 */
	 struct ramfs_node_t *children;
	 /* 双亲节点 */
	 struct ramfs_node_t *parent;

	 /* 引用链表 */
	 struct ramfs_data_t *ref;
	 /* 计数, 包括不在链表里的计数 */
	 uint32_t ref_count;

	 /* 如果是 mount point, 需要知道设备的代码 */
	 uint8_t dcode;
	 uint32_t size;
	 /* 所在内存的位置 */
	 void *data;
};

struct iramfs_node_t
{
	 /* 文件名 */
	 char name[RAMFS_NAME_LENGTH + 1];
	 /* 类型 */
	 uint8_t type;

	 /* 所在层次 */
	 uint32_t level;

	 /* 如果是 mount point, 需要知道设备的代码 */
	 uint8_t dcode;
	 uint32_t size;
};

struct ramfs_data_t
{
	 /* 节点 */
	 struct ramfs_node_t *node;
	 
	 /* 所有指向同一个 ramfs_node_t 的 data 组成一个双向循环列表 */
	 struct ramfs_data_t *next;
	 struct ramfs_data_t *prev;

	 bool dirty;
	 
	 union
	 {
		  /* 读写指针 */
		  int32_t ptr;
		  /* 浏览指针 */
		  void *data;
	 };
};

void init_ramfs_driver(void);

/* 导入 ramfs */
int import_ramfs(struct iramfs_node_t *r, struct fs_node_t *node);
/* 导出 ramfs */
int export_ramfs(void *data, void (*putch)(char, void*), struct fs_node_t *root);
/* 创建 ramfs */
int create_ramfs(struct fs_node_t *node);

#endif /* _EKU_RAMFS_H_ */
